VersioningStep.java
package org.codefilarete.stalactite.engine.configurer.dslresolver;
import java.util.Date;
import org.codefilarete.reflection.AccessorDefinition;
import org.codefilarete.reflection.ReadWritePropertyAccessPoint;
import org.codefilarete.stalactite.dsl.entity.EntityMappingConfiguration;
import org.codefilarete.stalactite.dsl.entity.OptimisticLockOption;
import org.codefilarete.stalactite.dsl.naming.ColumnNamingStrategy;
import org.codefilarete.stalactite.engine.configurer.model.Entity.Versioning;
import org.codefilarete.stalactite.sql.ddl.structure.Column;
import org.codefilarete.stalactite.sql.ddl.structure.Table;
import org.codefilarete.tool.Reflections;
import org.codefilarete.tool.exception.NotImplementedException;
import org.codefilarete.tool.function.Serie;
import static org.codefilarete.tool.Nullable.nullable;
public class VersioningStep<C, I, T extends Table<T>, V> {
public Versioning<C, V, T> findVersioning(EntityMappingConfiguration<C, I> entityMappingConfiguration, T table, ColumnNamingStrategy columnNamingStrategy) {
OptimisticLockOption<C, V> optimisticLockOption = (OptimisticLockOption<C, V>) entityMappingConfiguration.getOptimisticLockOption();
Versioning<C, V, T> versioningStrategy = null;
if (optimisticLockOption != null) {
Serie<V> serie = nullable(optimisticLockOption.getSerie()).getOr(() -> findSerie(AccessorDefinition.giveDefinition(optimisticLockOption.getVersionAccessor()).getMemberType()));
Column<T, V> versionColumn = buildColumn(optimisticLockOption.getVersionAccessor(), table, columnNamingStrategy);
versioningStrategy = new Versioning<>(optimisticLockOption.getVersionAccessor(), versionColumn, serie);
}
return versioningStrategy;
}
private Column<T, V> buildColumn(ReadWritePropertyAccessPoint<C, V> versionAccessor, T table, ColumnNamingStrategy columnNamingStrategy) {
AccessorDefinition versioningDefinition = AccessorDefinition.giveDefinition(versionAccessor);
String versioningColumnName = columnNamingStrategy.giveName(versioningDefinition);
boolean isColumnNullable = !Reflections.isPrimitiveType(versioningDefinition.getMemberType());
// Column addition should be shared in EmbeddableMappingBuilder but the class is shared by different use cases for which the
// versioning is not relevant, so this particularity is left here
return table.addColumn(versioningColumnName, versioningDefinition.getMemberType(), null, isColumnNullable);
}
private Serie<V> findSerie(Class<V> propertyType) {
Serie<V> serie;
if (Integer.class.isAssignableFrom(propertyType) || int.class.isAssignableFrom(propertyType)) {
serie = (Serie<V>) Serie.INTEGER_SERIE;
} else if (Long.class.isAssignableFrom(propertyType) || long.class.isAssignableFrom(propertyType)) {
serie = (Serie<V>) Serie.LONG_SERIE;
} else if (Date.class.isAssignableFrom(propertyType)) {
serie = (Serie<V>) Serie.NOW_SERIE;
} else {
throw new NotImplementedException("Type of versioned property is not implemented, please provide a "
+ Serie.class.getSimpleName() + " for it : " + Reflections.toString(propertyType));
}
return serie;
}
}